package com.bage.finance.biz.service.impl;

import com.bage.common.exception.BizException;
import com.bage.common.exception.ParameterException;
import com.bage.finance.biz.domain.MemberBindPhone;
import com.bage.finance.biz.dto.form.PhoneRegisterForm;
import com.bage.finance.biz.enums.SmsCodeTypeEnum;
import com.bage.finance.biz.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Objects;

@Service
@RequiredArgsConstructor
@Slf4j
public class MemberRegServiceImpl implements MemberRegService {

    final MemberLoginService memberLoginService;
    final RedissonClient redissonClient;
    final MemberBindPhoneService memberBindPhoneService;
    final TransactionTemplate transactionTemplate;
    final TenantService tenantService;
    final MemberService memberService;

    /**
     * 手机注册
     *
     * @param form
     * @return
     */
    @Override
    public Long phoneReg(PhoneRegisterForm form) {
        // 密码校验
        if (!Objects.equals(form.getPassword(), form.getConfirmPassword())) {
            throw new ParameterException("两次密码输入不一致");
        }
        // 短信验证码校验
        memberLoginService.checkSmsCode(form.getPhone(), form.getSmsCode(), SmsCodeTypeEnum.REG.getCode());

        RLock rLock = redissonClient.getLock("PHONE_REG:" + form.getPhone());

        try {
            rLock.lock();
            MemberBindPhone memberByPhone = memberBindPhoneService.getMemberByPhone(form.getPhone());
            // 手机号是否注册
            if (memberByPhone != null) {
                log.warn("手机号：{}已注册", form.getPhone());
                throw new BizException("手机号已注册");
            }
            Long memberId = transactionTemplate.execute(transactionStatus -> {
                long tenantId = tenantService.add();
                long id = memberService.reg(tenantId);
                if (id <= 0) {
                    throw new BizException("注册异常");
                }
                memberBindPhoneService.reg(form.getPhone(), id, form.getPassword());
                return id;
            });
            if (memberId == null) {
                throw new BizException("注册失败");
            }
            return memberId;
        } catch (Exception e) {
            throw new BizException("注册失败", e);
        } finally {
            rLock.unlock();
        }

    }
}
